﻿using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace System
{

    public static class StringExtensions
    {

        public static byte[] ToBytes(this string value)
        {
            return Encoding.UTF8.GetBytes(value);
        }
        public static string MD5Encrypt(this string value)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] result = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(value));
            StringBuilder sBuilder = new StringBuilder();
            foreach (byte b in result)
            {
                sBuilder.Append(b.ToString("X2"));
            }
            return sBuilder.ToString();
        }
        public static string ConvertCSVValue(this string value)
        {
            string result = null;
            value = value.Replace("\"", "\"\"");
            if (value.IndexOf(",") > 0)
            {
                result = "\"" + value + "\"";
                return result;
            }
            return value;
        }

        /// <summary>
        /// 将首字母转换为小写
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetFirstLowerStr(this string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                if (str.Length == 1)
                {
                    return str.ToLower();
                }
                return char.ToLower(str[0]) + str.Substring(1);
            }
            return str;
        }
        /// <summary>
        /// 将首字母转换为大写
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetFirstUpperStr(this string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                if (str.Length == 1)
                {
                    return str.ToUpper();
                }
                return char.ToUpper(str[0]) + str.Substring(1);
            }
            return str;
        }

        /// <summary>
        /// 添加字符串并换行
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string AddLine(this string str,string append)
        {
            if (!string.IsNullOrEmpty(str))
            {
            
                return str+= $"{ DateTime.Now.ToString()}:{append}\r\n";
            }
            return str;
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="express"></param>
        /// <param name="keyContainerName"></param>
        /// <returns></returns>
        public static string Encryption(this string express, string keyContainerName = "x")
        {
            CspParameters param = new CspParameters();
            //密匙容器的名称
            param.KeyContainerName = keyContainerName;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
            {
                byte[] plaindata = Encoding.Default.GetBytes(express);//将要加密的字符串转换为字节数组
                byte[] encryptdata = rsa.Encrypt(plaindata, false);//将加密后的字节数据转换为新的加密字节数组
                return Convert.ToBase64String(encryptdata);//将加密后的字节数组转换为字符串
            }
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="ciphertext">需要解密的字符串</param>
        /// <returns>解密后的字符串</returns>
        public static string Decrypt(this string ciphertext, string keyContainerName = "x")
        {
            CspParameters param = new CspParameters();
            param.KeyContainerName = keyContainerName;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
            {
                byte[] encryptdata = Convert.FromBase64String(ciphertext);
                byte[] decryptdata = rsa.Decrypt(encryptdata, false);
                return Encoding.Default.GetString(decryptdata);
            }
        }

        /// <summary>
        /// 补齐字符串
        /// </summary>
        /// <param name="str">被补齐的字符串</param>
        /// <param name="length">长度</param>
        /// <param name="c">填充的字符</param>
        /// <param name="dir">补齐的方向 L左补齐 R 右补齐</param>
        /// <returns>补齐后的字符串</returns>
        public static string ComplementString(this string str, int length, char c = ' ', string dir = "L")
        {

            if (str.Length < length)
            {
                int len = length - str.Length;
                StringBuilder s = new StringBuilder();
                for (int i = 0; i < len; i++)
                {
                    s.Append(c);
                }
                if (dir.ToUpper() == "L")
                {
                    return String.Concat(s.ToString(), str);
                }
                else
                {
                    return String.Concat(str, s.ToString());
                }
            }
            return str;

        }

        /// <summary>
        /// 从最后开始截取字符串
        /// </summary>
        /// <param name="str">被截取的字符串</param>
        /// <param name="len">总位数</param>
        /// <returns></returns>
        public static string FromLastSubString(this string str, int len)
        {
            if (string.IsNullOrEmpty(str))
            {
                return string.Empty;
            }
            if (len <= 0)
            {
                return string.Empty;
            }
            if (str.Length <= len)
            {
                return str;
            }
            int startIndex = str.Length - len;
            return str.Substring(startIndex, len);
        }
        /// <summary>
        /// 字符串转化为字典
        /// </summary>
        /// <param name="str">被转化的字符串</param>
        /// <param name="keyValueSeparatorChar">Key Value之间的分隔字符</param>
        /// <param name="itemSeparatorChar">项之间的分隔符</param>
        /// <returns>字典Dictionary</returns>
        /// <example>string = "key1=val1;key2=val2"; str.ToDictionary('=',';')</example>
        public static Dictionary<string,string> ToDictionary(this string str, char keyValueSeparatorChar, char itemSeparatorChar)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(str))
            {
                string[] strArray = str.Split(itemSeparatorChar);
                foreach (string dicString in strArray)
                {
                    string[] keyValArray = dicString.Split(keyValueSeparatorChar);
                    if (keyValArray.Length == 2)
                    {
                        if (dic.ContainsKey(keyValArray[0]))
                        {
                            dic[keyValArray[0]] = keyValArray[1];
                        }
                        else
                        {
                            dic.Add(keyValArray[0], keyValArray[1]);
                        }
                    }
                }

            }
            return dic;
        }

        /// <summary>
        /// 根据给定的起始符号和终止符号来获得一个中间的字符串
        /// </summary>
        /// <param name="str">原始字符串</param>
        /// <param name="startChar">起始符号</param>
        /// <param name="endChar">终止符号</param>
        /// <returns>中间的字符串</returns>
        public static string GetSubStringBySymbol(this string str, char startChar, char endChar)
        {
            int startIndex = str.IndexOf(startChar);
            int endIndex = str.IndexOf(endChar);
            if (startIndex == -1 || endIndex == -1 || startIndex >= endIndex)
            {
                return string.Empty;
            }
            return str.Substring(startIndex + 1, endIndex - startIndex - 1);
        }
        /// <summary>
        /// 获得控件的Code
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetControlCode(this string str)
        {
            return GetSubStringBySymbol(str, '{', '}');
        }

        public static string ConvertToScriptString(this string value)
        {
            string newString;
            newString = value.Replace("[", "$('[RefProrName=").Replace("]", "]').attr('value')");
            return newString;
        }

        public static int AdvanceCompareTo(this string value, string str)
        {
            if (value == null && str == null)
            {
                return 0;
            }
            if (value == null)
            {
                return -1;
            }
            if (str == null)
            {
                return 1;
            }
            if (str.Length == value.Length)
            {
                return value.CompareTo(str);
            }

            return value.Length.CompareTo(str.Length);

        }


        public static bool IsExtensibleMarkup(this string value)
        {
            bool flag = false;
            try
            {
                string valueT = value.Trim();
                string vBegin = valueT.Substring(0, 2);
                if (vBegin == "{%")
                {
                    string vEnd = valueT.Substring(valueT.Length - 2, 2);
                    if (vEnd == "%}")
                    {
                        flag = true;
                    }
                }
            }
            catch (Exception)
            {
              
            }
            return flag;
        }

        public static string[] RetFlag(this string value)
        {
            string str = SubExpression(value).Trim();
            string flag = "";
            string[] strs = str.Split(':');
            if (strs.Length > 1)
            {
                if (strs[0].Trim().ToLower() == "x")
                {
                    flag = strs[1];
                }
            }
            return flag.Split(' ');
        }

        private static string SubExpression(this string value)
        {
            string valueT = value.Trim();
            string str1 = valueT.Substring(0, valueT.Length - 2);
            return str1.Substring(2);
        }

        public static bool IsEmpty(this string value)
        {
            return String.IsNullOrEmpty(value);
        }

        
        public static int AsInt(this string value)
        {
            return As<int>(value);
        }

        
        public static int AsInt(this string value, int defaultValue)
        {
            return As<int>(value, defaultValue);
        }

        public static decimal AsDecimal(this string value)
        {
            return As<decimal>(value);
        }

        public static decimal AsDecimal(this string value, decimal defaultValue)
        {
            return As<decimal>(value, defaultValue);
        }

        
        public static float AsFloat(this string value)
        {
            return As<float>(value);
        }

        
        public static float AsFloat(this string value, float defaultValue)
        {
            return As<float>(value, defaultValue);
        }

        public static DateTime AsDateTime(this string value)
        {
            return As<DateTime>(value);
        }

        public static DateTime AsDateTime(this string value, DateTime defaultValue)
        {
            return As<DateTime>(value, defaultValue);
        }

        public static TValue As<TValue>(this string value)
        {
            return As<TValue>(value, default(TValue));
        }

        
        public static bool AsBool(this string value)
        {
            return As<bool>(value, false);
        }

        
        public static bool AsBool(this string value, bool defaultValue)
        {
            return As<bool>(value, defaultValue);
        }

        public static object As(this string value, Type type, object defaultValue)
        {
            try
            {
                TypeConverter converter = TypeDescriptor.GetConverter(type);
                if (converter.CanConvertFrom(typeof(string)))
                {
                    return converter.ConvertFrom(value);
                }
                // try the other direction
                converter = TypeDescriptor.GetConverter(typeof(string));
                if (converter.CanConvertTo(type))
                {
                    return converter.ConvertTo(value, type);
                }
            }
            catch (Exception)
            {
                // eat all exceptions and return the defaultValue, assumption is that its always a parse/format exception
            }
            return defaultValue;
        }
        public static TValue As<TValue>(this string value, TValue defaultValue)
        {
            try
            {
                TypeConverter converter = TypeDescriptor.GetConverter(typeof(TValue));
                if (converter.CanConvertFrom(typeof(string)))
                {
                    return (TValue)converter.ConvertFrom(value);
                }
                // try the other direction
                converter = TypeDescriptor.GetConverter(typeof(string));
                if (converter.CanConvertTo(typeof(TValue)))
                {
                    return (TValue)converter.ConvertTo(value, typeof(TValue));
                }
            }
            catch (Exception)
            {
                // eat all exceptions and return the defaultValue, assumption is that its always a parse/format exception
            }
            return defaultValue;
        }

        
        public static bool IsBool(this string value)
        {
            return Is<bool>(value);
        }

        
        public static bool IsInt(this string value)
        {
            return Is<int>(value);
        }

        public static bool IsDecimal(this string value)
        {
            return Is<decimal>(value);
        }

        
        public static bool IsFloat(this string value)
        {
            return Is<float>(value);
        }

        public static bool IsDateTime(this string value)
        {
            return Is<DateTime>(value);
        }

        public static string GetPassWord(this string value)
        {
            string Password = "";
            for (int i = 0; i < value.ToCharArray().Length; i++)
			{
                Password += "*";
			}
            return Password;
        }

        
        public static bool Is<TValue>(this string value)
        {
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(TValue));
            if (converter != null)
            {
                if (converter.CanConvertFrom(typeof(string)))
                {
                    return converter.IsValid(value);
                }
            }
            return false;
        }


        public delegate string GetStringValue(string str);




        public static string StringExpressionProcHelp(this string value, char begChar, 
            char endChar, GetStringValue help)
        {

            bool isBegChar = false;
            char[] charArray = value.ToCharArray();
            List<char> charList = new List<char>();
            List<char> charTmpList = new List<char>();
            for (int i = 0; i < charArray.Length; i++)
            {
                if (charArray[i] == begChar)
                {
                    if (!isBegChar)
                    {
                        isBegChar = true;
                    }
                    else
                    {
                        charList.Add(charArray[i]);
                    }
                }
                else if (charArray[i] == endChar)
                {
                    if (isBegChar)
                    {
                        isBegChar = false;
                        char[] tmpArray = charTmpList.ToArray();
                        String s = new string(tmpArray);
                        charList.AddRange(help(s).ToCharArray());
                        charTmpList.Clear();
                    }
                    else
                    {
                        charList.Add(charArray[i]);
                    }
                }
                else
                {
                    if (isBegChar)
                    {
                        charTmpList.Add(charArray[i]);
                    }
                    else
                    {
                        charList.Add(charArray[i]);
                    }
                }
            }
            return new string(charList.ToArray());

        }
    }
}
